#pragma once
#include <cassert>
#include <cstddef>
#include <iterator>
#include <type_traits>
#include <utility>

#if defined(__cpp_lib_ranges) && (__cpp_lib_ranges >= 201911L)
#define KP_HAS_STD_RANGES
#endif

#ifndef KP_HAS_STD_RANGES

/**
 * @file view.h
 * @brief 在缺少 std::ranges 的环境中提供轻量级视图适配器集合。
 *
 * 设计初衷：
 * 1. 兼容 C++11/14/17 等老标准，弥补 std::ranges 缺失。
 * 2. 提供与 std::ranges 风格一致的管道化调用（r | adapt）。
 * 3. 所有视图均为惰性求值，不提前分配额外内存，迭代时按需计算。
 * 4. 通过 ADL 检测用户自定义的 begin/end，保证与第三方容器无缝协作。
 * 5. 统一使用 as_view_t 做“视图化”包装，确保适配器内部只依赖 begin/end 语义，
 *    而不依赖容器本身的生命周期。
 */

namespace kp
{

using std::begin;
using std::end;

/**
 * @brief 通过 ADL 取得范围 r 的起始迭代器。
 * @tparam R 任意范围类型（数组、STL 容器、自定义类型）
 * @param r  范围实例
 * @return   调用 ADL 找到的 begin(r)
 * @note     内部先 using std::begin，再调用无限定 begin，兼顾标准与用户扩展。
 */
template <class R>
auto
adl_begin(R && r) -> decltype(begin(std::forward<R>(r)))
{
    return begin(std::forward<R>(r));
}

/**
 * @brief 通过 ADL 取得范围 r 的终止哨兵。
 * @copydetails adl_begin
 */
template <class R>
auto
adl_end(R && r) -> decltype(end(std::forward<R>(r)))
{
    return end(std::forward<R>(r));
}

/**
 * @brief 取范围 R 的迭代器类型。
 * @tparam R 范围类型
 * @note  用于视图内部声明 iterator / const_iterator。
 */
template <class R>
using range_begin_t = decltype(adl_begin(std::declval<R &>()));

/**
 * @brief 取范围 R 的哨兵类型。
 * @copydetails range_begin_t
 */
template <class R>
using range_end_t = decltype(adl_end(std::declval<R &>()));

/**
 * @brief 取范围 R 的元素值类型（去引用 & 去 cv）。
 * @tparam R 范围类型
 * @note  用于 transform_view 等推导 value_type。
 */
template <class R>
using range_value_t =
    typename std::remove_reference<decltype(*adl_begin(std::declval<R &>()))>::type;

/**
 * @brief 统一比较迭代器与哨兵是否相等。
 * @tparam It  迭代器类型
 * @tparam End 哨兵类型（可能与 It 相同，也可能是 sentinel）
 * @note  对于常见情况直接调用 it == ed；后续若引入 sentinel 特化可在此扩展。
 */
template <class It, class End>
inline bool
iter_equal(const It & it, const End & ed)
{
    return it == ed;
}

/**
 * @brief 管道化基类，为所有视图适配器提供 operator| 语法糖。
 * @tparam Derived 实际适配器类型（CRTP）
 *
 * 设计要点：
 * 1. 仅提供友元 operator|，避免污染全局命名空间。
 * 2. 支持左值/右值范围，完美转发保证性能。
 */
template <class Derived>
struct pipeable
{
    /**
     * @brief 管道语法：range | adaptor
     * @tparam R 范围类型（可 const& / & / &&）
     * @param r  范围实例
     * @param d  适配器实例（通常为空对象）
     * @return   适配器调用结果，即视图对象
     */
    template <class R>
    friend auto operator|(R && r, const Derived & d)
    {
        return d(std::forward<R>(r));
    }
};

/**
 * @brief 将任意范围包装成“视图”的最小壳。
 * @tparam R 原始范围类型（按值存储，内部 move 构造）
 *
 * 设计初衷：
 * 1. 统一所有视图适配器的输入，使得适配器内部只依赖 begin/end，
 *    而不依赖容器生命周期。
 * 2. 提供 const / non-const 两套 begin/end，支持 const R 的视图。
 * 3. 提供 base() 访问原始范围，与 std::views::all 行为一致。
 */
template <class R>
class as_view_t
{
public:
    using iterator = range_begin_t<R>; ///< 迭代器类型
    using sentinel = range_end_t<R>;   ///< 哨兵类型

    /**
     * @brief 构造视图，按值接管范围（要求调用者保证外部不再使用原对象）。
     * @param r 原始范围（将 move 进内部）
     */
    explicit as_view_t(R r) : r_(std::move(r)) {}

    ///@{
    /**
     * @brief 返回起始迭代器（non-const）
     */
    iterator begin() { return adl_begin(r_); }
    /**
     * @brief 返回终止哨兵（non-const）
     */
    sentinel end() { return adl_end(r_); }
    ///@}

    ///@{
    /**
     * @brief 返回 const 版本起始迭代器
     * @note  仅当 R 本身支持 const begin 时可用。
     */
    auto begin() const -> range_begin_t<const R> { return adl_begin(static_cast<const R &>(r_)); }
    /**
     * @brief 返回 const 版本终止哨兵
     */
    auto end() const -> range_end_t<const R> { return adl_end(static_cast<const R &>(r_)); }
    ///@}

    ///@{
    /**
     * @brief 访问原始范围（多种引用限定符重载）
     */
    R & base() & { return r_; }
    const R & base() const & { return r_; }
    R && base() && { return std::move(r_); }
    ///@}

private:
    R r_; ///< 按值保存的范围实例
};

/**
 * @brief as_view 的函数对象版本，方便管道化。
 */
struct as_view_fn : pipeable<as_view_fn>
{
    /**
     * @brief 将任意范围转换为 as_view_t 视图。
     * @tparam R 范围类型（自动 decay）
     * @param r  范围实例
     * @return   as_view_t 实例
     */
    template <class R>
    auto operator()(R && r) const
    {
        return as_view_t<typename std::decay<R>::type>(std::forward<R>(r));
    }
};
/**
 * @brief 全局内联实例，提供 kp::as_view 调用点。
 */
inline constexpr as_view_fn as_view{};

/**
 * @brief 对范围元素进行惰性变换的视图。
 * @tparam R  原始范围类型
 * @tparam F  一元变换函数（可函数指针、函数对象、lambda）
 *
 * 设计初衷：
 * 1. 与 std::views::transform 语义一致：迭代时按需调用 f(elem)。
 * 2. 迭代器类别继承自底层，若底层为 RandomAccess，则变换后仍为 RandomAccess。
 * 3. 支持 const 迭代：当底层范围支持 const begin 时，提供 const_iterator。
 *
 * 实现要点：
 * 1. 内部保存 as_view_t<R> 和 F 的实例，均按值存储（小对象优化由编译器完成）。
 * 2. iter_t<Const> 模板同时支持 const / non-const 两套迭代器。
 * 3. operator* 直接返回 f(*it)，不缓存结果，保证惰性。
 */
template <class R, class F>
class transform_view
{
    using ItBase = range_begin_t<R>; ///< 底层迭代器类型
    using EndBase = range_end_t<R>;  ///< 底层哨兵类型

    /**
     * @brief 实际迭代器，按需调用 F 进行变换。
     * @tparam Const 为 true 时代表 const 迭代器
     */
    template <bool Const>
    class iter_t
    {
        using View = typename std::conditional<Const, const transform_view, transform_view>::type;
        using BaseR = typename std::conditional<Const, const R, R>::type;

    public:
        using iterator_category = typename std::iterator_traits<ItBase>::iterator_category;
        using difference_type = typename std::iterator_traits<ItBase>::difference_type;
        using reference = decltype(std::declval<F &>()(*std::declval<ItBase &>()));
        using value_type = typename std::remove_reference<reference>::type;

        iter_t() = default;
        /**
         * @brief 构造迭代器
         * @param v  指向父视图（用于访问 F）
         * @param it 底层迭代器
         */
        // Pass heavy iterator by const reference, store by value internally
        iter_t(View * v, const ItBase & it) : v_(v), it_(it) {}

        bool operator==(const iter_t & other) const { return it_ == other.it_; }
        bool operator!=(const iter_t & other) const { return !(*this == other); }

        iter_t & operator++()
        {
            ++it_;
            return *this;
        }
        iter_t operator++(int)
        {
            auto tmp = *this;
            ++*this;
            return tmp;
        }

        /**
         * @brief 惰性求值：返回 f(*it)
         */
        reference operator*() const { return v_->f_(*it_); }

    private:
        View * v_{};  ///< 父视图指针
        ItBase it_{}; ///< 底层迭代器
    };

public:
    using iterator = iter_t<false>;      ///< non-const 迭代器
    using const_iterator = iter_t<true>; ///< const 迭代器

    /**
     * @brief 构造 transform_view
     * @param r 原始范围（将 move 进内部 as_view）
     * @param f 变换函数（将 move 进内部）
     */
    transform_view(R r, F f) : r_(std::move(r)), f_(std::move(f)) {}

    /**
     * @brief 返回起始迭代器（non-const）
     */
    iterator begin() { return iterator(this, adl_begin(r_)); }
    /**
     * @brief 返回终止迭代器（non-const）
     */
    iterator end() { return iterator(this, adl_end(r_)); }

    /**
     * @brief 返回 const 起始迭代器
     */
    const_iterator begin() const
    {
        return const_iterator(this, adl_begin(static_cast<const R &>(r_)));
    }
    /**
     * @brief 返回 const 终止迭代器
     */
    const_iterator end() const { return const_iterator(this, adl_end(static_cast<const R &>(r_))); }

private:
    as_view_t<R> r_; ///< 视图化后的原始范围
    F f_;            ///< 变换函数实例
};

/**
 * @brief transform_view 的函数对象版本，支持管道化。
 */
struct transform_fn : pipeable<transform_fn>
{
    /**
     * @brief 延迟绑定的适配器（柯里化）
     * @tparam F 变换函数类型
     */
    template <class F>
    struct binder : pipeable<binder<F>>
    {
        F f; ///< 保存变换函数
        explicit binder(F ff) : f(std::move(ff)) {}
        /**
         * @brief 实际构造 transform_view
         * @tparam R 范围类型
         * @param r  范围实例
         * @return   transform_view 实例
         */
        template <class R>
        auto operator()(R && r) const
        {
            using RR = typename std::decay<R>::type;
            using FF = F;
            return transform_view<as_view_t<RR>, FF>(as_view(std::forward<R>(r)), f);
        }
    };
    /**
     * @brief 接收变换函数，返回延迟绑定的 binder
     * @param f 变换函数
     * @return  binder 实例
     */
    template <class F>
    auto operator()(F && f) const
    {
        return binder<typename std::decay<F>::type>(std::forward<F>(f));
    }
};
/**
 * @brief 全局内联实例，提供 kp::transform 调用点。
 */
inline constexpr transform_fn transform{};

/**
 * @brief 惰性过滤视图，仅保留满足谓词的元素。
 * @tparam R   原始范围类型
 * @tparam Pred 一元谓词，返回 true 的元素被保留
 *
 * 设计初衷：
 * 1. 与 std::views::filter 语义一致：迭代时跳过不满足条件的元素。
 * 2. 由于需要跳过元素，迭代器类别退化为 InputIterator（保守策略）。
 * 3. 支持 const 迭代，与 transform_view 保持一致。
 *
 * 实现要点：
 * 1. 内部保存 as_view_t<R> 和 Pred 实例。
 * 2. 迭代器构造时立即调用 satisfy() 定位到首个满足条件的元素。
 * 3. operator++ 继续跳过不满足条件的元素。
 */
template <class R, class Pred>
class filter_view
{
    using ItBase = range_begin_t<R>; ///< 底层迭代器
    using EndBase = range_end_t<R>;  ///< 底层哨兵

    /**
     * @brief 实际迭代器，自动跳过不满足 pred 的元素。
     * @tparam Const 为 true 时代表 const 迭代器
     */
    template <bool Const>
    class iter_t
    {
        using View = typename std::conditional<Const, const filter_view, filter_view>::type;

    public:
        using iterator_category = std::input_iterator_tag; ///< 保守策略
        using difference_type = std::ptrdiff_t;
        using value_type = range_value_t<R>;
        using reference = decltype(*std::declval<ItBase &>());

        iter_t() = default;
        /**
         * @brief 构造迭代器并立即定位到首个满足条件的元素
         * @param v  父视图指针
         * @param it 起始迭代器
         * @param ed 终止哨兵
         */
        // Pass heavy iterator/sentinel by const reference, store by value internally
        iter_t(View * v, const ItBase & it, const EndBase & ed) : v_(v), it_(it), ed_(ed)
        {
            satisfy();
        }

        /**
         * @brief 跳过不满足条件的元素
         */
        void satisfy()
        {
            while (!iter_equal(it_, ed_) && !v_->pred_(*it_))
                ++it_;
        }

        bool operator==(const iter_t & other) const { return iter_equal(it_, other.it_); }
        bool operator!=(const iter_t & other) const { return !(*this == other); }

        iter_t & operator++()
        {
            ++it_;
            satisfy();
            return *this;
        }
        iter_t operator++(int)
        {
            auto tmp = *this;
            ++*this;
            return tmp;
        }

        /**
         * @brief 返回底层元素引用（已保证满足 pred）
         */
        reference operator*() const { return *it_; }

    private:
        View * v_{};   ///< 父视图
        ItBase it_{};  ///< 底层迭代器
        EndBase ed_{}; ///< 底层哨兵
    };

public:
    using iterator = iter_t<false>;      ///< non-const 迭代器
    using const_iterator = iter_t<true>; ///< const 迭代器

    /**
     * @brief 构造 filter_view
     * @param r 原始范围
     * @param p 谓词函数
     */
    filter_view(R r, Pred p) : r_(std::move(r)), pred_(std::move(p)) {}

    /**
     * @brief 返回起始迭代器（已定位到首个满足条件的元素）
     */
    iterator begin() { return iterator(this, adl_begin(r_), adl_end(r_)); }
    /**
     * @brief 返回终止迭代器
     */
    iterator end() { return iterator(this, adl_end(r_), adl_end(r_)); }

    /**
     * @brief 返回 const 起始迭代器
     */
    const_iterator begin() const
    {
        return const_iterator(
            this, adl_begin(static_cast<const R &>(r_)), adl_end(static_cast<const R &>(r_)));
    }
    /**
     * @brief 返回 const 终止迭代器
     */
    const_iterator end() const
    {
        return const_iterator(
            this, adl_end(static_cast<const R &>(r_)), adl_end(static_cast<const R &>(r_)));
    }

private:
    as_view_t<R> r_; ///< 视图化后的原始范围
    Pred pred_;      ///< 谓词实例
};

/**
 * @brief 过滤视图适配器的函数对象版本，支持管道化语法。
 * @details
 * 设计初衷：
 * 1. 与 std::views::filter 保持一致，提供惰性过滤能力。
 * 2. 通过 binder 延迟绑定谓词，使 `range | filter(pred)` 语法成为可能。
 * 3. 所有状态按值存储，避免悬空指针，保证线程安全（无共享可变状态）。
 *
 * 用法示例：
 * @code
 * std::vector<int> v{1,2,3,4,5};
 * auto evens = v | kp::filter([](int x){ return x%2==0; });
 * @endcode
 */
struct filter_fn : pipeable<filter_fn>
{
    /**
     * @brief 延迟绑定谓词的中间函子，负责最终构造 filter_view。
     * @tparam P 谓词类型（可函数指针、函数对象、lambda）
     *
     * 设计要点：
     * 1. 继承 pipeable<binder<P>> 以获得 operator| 能力。
     * 2. 在 operator() 内部将范围包装为 as_view_t，确保迭代器语义统一。
     */
    template <class P>
    struct binder : pipeable<binder<P>>
    {
        P p; ///< 按值保存谓词，保证生命周期安全

        /**
         * @brief 构造 binder，按值接收谓词。
         * @param pp 谓词实例
         */
        explicit binder(P pp) : p(std::move(pp)) {}

        /**
         * @brief 接收范围并生成 filter_view。
         * @tparam R 原始范围类型（万能引用）
         * @param r  原始范围实例
         * @return   filter_view<as_view_t<RR>, PP>
         *
         * 实现要点：
         * 1. 使用 as_view 包装原始范围，统一迭代器入口。
         * 2. 强制 decay 消除引用，避免视图内部出现引用成员。
         */
        template <class R>
        auto operator()(R && r) const
        {
            using RR = typename std::decay<R>::type;
            using PP = P;
            return filter_view<as_view_t<RR>, PP>(as_view(std::forward<R>(r)), p);
        }
    };

    /**
     * @brief 接收谓词并返回延迟绑定的 binder。
     * @tparam P 谓词类型
     * @param p  谓词实例
     * @return   binder<P> 临时对象
     */
    template <class P>
    auto operator()(P && p) const
    {
        return binder<typename std::decay<P>::type>(std::forward<P>(p));
    }
};

/**
 * @brief 全局内联实例，提供 kp::filter 调用点。
 */
inline constexpr filter_fn filter{};

// =================== take_view / drop_view ===================

/**
 * @brief 惰性“取前 n 个元素”的视图。
 * @tparam R 原始范围类型
 *
 * 设计初衷：
 * 1. 与 std::views::take 语义一致：迭代时最多产生 n 个元素。
 * 2. 不提前分配内存，迭代器类别与底层保持一致（若底层为 RandomAccess，则仍为 RandomAccess）。
 * 3. 支持 const 迭代，当底层范围支持 const begin 时可用。
 *
 * 实现要点：
 * 1. 内部保存 as_view_t<R> 和长度 n，均按值存储。
 * 2. end() 通过 take_end 辅助函数按需前进 n 步，若不足 n 步则到底层结尾自然停止。
 * 3. 提供 const 重载，保证 const R 也能生成对应迭代器。
 */
template <class R>
class take_view
{
public:
    using iterator = range_begin_t<R>; ///< 迭代器类型与底层一致
    using sentinel = range_end_t<R>;   ///< 哨兵类型与底层一致

    /**
     * @brief 构造 take_view
     * @param r 原始范围（将 move 进内部）
     * @param n 欲取元素个数
     */
    take_view(R r, std::size_t n) : r_(std::move(r)), n_(n) {}

    /**
     * @brief 返回起始迭代器（non-const）
     */
    iterator begin() { return adl_begin(r_); }

    /**
     * @brief 返回终止迭代器（最多前进 n 步）
     */
    iterator end() { return take_end(adl_begin(r_), adl_end(r_), n_); }

    /**
     * @brief 返回 const 起始迭代器
     */
    auto begin() const -> range_begin_t<const R> { return adl_begin(static_cast<const R &>(r_)); }

    /**
     * @brief 返回 const 终止迭代器
     */
    auto end() const -> range_begin_t<const R>
    {
        return take_end(
            adl_begin(static_cast<const R &>(r_)), adl_end(static_cast<const R &>(r_)), n_);
    }

private:
    /**
     * @brief 辅助函数：从 it 出发最多前进 n 步，或到达 ed 即停。
     * @tparam It 迭代器类型
     * @tparam Ed 哨兵类型
     * @param it 起始迭代器
     * @param ed 终止哨兵
     * @param n  剩余步数
     * @return   终止位置迭代器
     */
    template <class It, class Ed>
    // Accept iterator/sentinel by const reference to avoid large-by-value ABI issues
    static It take_end(const It & it_in, const Ed & ed_in, std::size_t n)
    {
        auto it = it_in; // make local copy to advance
        auto ed = ed_in;
        while (n-- && !iter_equal(it, ed))
            ++it;
        return it;
    }

    R r_;           ///< 视图化后的原始范围
    std::size_t n_; ///< 欲取元素个数
};

/**
 * @brief take 视图的函数对象实现，支持管道化。
 * @details
 * 设计要点：
 * 1. 通过 binder 延迟绑定长度 n，使 `range | take(n)` 语法成为可能。
 * 2. 内部强制 decay 消除引用，确保视图按值语义管理资源。
 */
struct take_fn_impl : pipeable<take_fn_impl>
{
    /**
     * @brief 延迟绑定长度的中间函子。
     */
    struct binder : pipeable<binder>
    {
        std::size_t n; ///< 按值保存长度

        /**
         * @brief 构造 binder
         * @param nn 长度
         */
        explicit binder(std::size_t nn) : n(nn) {}

        /**
         * @brief 接收范围并生成 take_view。
         * @tparam R 原始范围类型
         * @param r  范围实例
         * @return   take_view 实例
         */
        template <class R>
        auto operator()(R && r) const
        {
            using RR = typename std::decay<R>::type;
            return take_view<as_view_t<RR>>(as_view(std::forward<R>(r)), n);
        }
    };

    /**
     * @brief 接收长度并返回延迟绑定的 binder。
     * @param n 长度
     * @return  binder 临时对象
     */
    auto operator()(std::size_t n) const { return binder{n}; }
};

/**
 * @brief 全局内联实例，提供 kp::take 调用点。
 */
inline constexpr take_fn_impl take{};

/**
 * @brief 惰性“丢弃前 n 个元素”的视图。
 * @tparam R 原始范围类型
 *
 * 设计初衷：
 * 1. 与 std::views::drop 语义一致：迭代时跳过前 n 个元素，剩余元素原样输出。
 * 2. 不提前分配内存，迭代器类别与底层保持一致。
 * 3. 支持 const 迭代。
 *
 * 实现要点：
 * 1. begin() 通过 drop_begin 辅助函数按需前进 n 步，若不足 n 步则到底层结尾。
 * 2. end() 直接返回底层 end，因为丢弃操作不影响终点。
 */
template <class R>
class drop_view
{
public:
    using iterator = range_begin_t<R>; ///< 迭代器类型与底层一致
    using sentinel = range_end_t<R>;   ///< 哨兵类型与底层一致

    /**
     * @brief 构造 drop_view
     * @param r 原始范围（将 move 进内部）
     * @param n 欲丢弃元素个数
     */
    drop_view(R r, std::size_t n) : r_(std::move(r)), n_(n) {}

    /**
     * @brief 返回起始迭代器（已跳过前 n 个元素）
     */
    iterator begin() { return drop_begin(adl_begin(r_), adl_end(r_), n_); }

    /**
     * @brief 返回终止迭代器（与底层一致）
     */
    sentinel end() { return adl_end(r_); }

    /**
     * @brief 返回 const 起始迭代器
     */
    auto begin() const -> range_begin_t<const R>
    {
        return drop_begin(
            adl_begin(static_cast<const R &>(r_)), adl_end(static_cast<const R &>(r_)), n_);
    }

    /**
     * @brief 返回 const 终止迭代器
     */
    auto end() const -> range_end_t<const R> { return adl_end(static_cast<const R &>(r_)); }

private:
    /**
     * @brief 辅助函数：从 it 出发最多前进 n 步，或到达 ed 即停。
     * @tparam It 迭代器类型
     * @tparam Ed 哨兵类型
     * @param it 起始迭代器
     * @param ed 终止哨兵
     * @param n  剩余步数
     * @return   跳过后的迭代器
     */
    template <class It, class Ed>
    // Accept iterator/sentinel by const reference to avoid large-by-value ABI issues
    static It drop_begin(const It & it_in, const Ed & ed_in, std::size_t n)
    {
        auto it = it_in; // local copy to advance
        auto ed = ed_in;
        while (n-- && !iter_equal(it, ed))
            ++it;
        return it;
    }

    R r_;           ///< 视图化后的原始范围
    std::size_t n_; ///< 欲丢弃元素个数
};

/**
 * @brief “丢弃前 n 个元素”视图的函数对象实现，支持管道化语法。
 *
 * 设计初衷：
 * 1. 与 std::views::drop 语义保持一致：迭代时跳过前 n 个元素，剩余元素原样输出。
 * 2. 通过 binder 延迟绑定长度 n，使 `range | drop(n)` 的管道写法成为可能。
 * 3. 所有状态按值存储，避免悬空引用，保证线程安全（无共享可变状态）。
 *
 * 实现要点：
 * 1. 内部使用 as_view 统一包装原始范围，确保迭代器入口一致。
 * 2. 强制 decay 消除引用，避免视图内部出现引用成员。
 * 3. 返回的 drop_view 为惰性求值，不提前分配内存。
 */
struct drop_fn : pipeable<drop_fn>
{
    /**
     * @brief 延迟绑定长度的中间函子，负责最终构造 drop_view。
     *
     * 设计要点：
     * 1. 继承 pipeable<binder> 以获得 operator| 能力。
     * 2. 在 operator() 内部将范围包装为 as_view_t，确保迭代器语义统一。
     */
    struct binder : pipeable<binder>
    {
        std::size_t n; ///< 按值保存长度，保证生命周期安全

        /**
         * @brief 构造 binder，按值接收长度。
         * @param nn 欲丢弃的元素个数
         */
        explicit binder(std::size_t nn) : n(nn) {}

        /**
         * @brief 接收范围并生成 drop_view。
         * @tparam R 原始范围类型（万能引用）
         * @param r  原始范围实例
         * @return   drop_view<as_view_t<RR>>
         *
         * 实现要点：
         * 1. 使用 as_view 包装原始范围，统一迭代器入口。
         * 2. 强制 decay 消除引用，避免视图内部出现引用成员。
         */
        template <class R>
        auto operator()(R && r) const
        {
            using RR = typename std::decay<R>::type;
            return drop_view<as_view_t<RR>>(as_view(std::forward<R>(r)), n);
        }
    };

    /**
     * @brief 接收长度并返回延迟绑定的 binder。
     * @param n 长度
     * @return  binder 临时对象
     */
    auto operator()(std::size_t n) const { return binder{n}; }
};

/**
 * @brief 全局内联实例，提供 kp::drop 调用点。
 */
inline constexpr drop_fn drop{};

// =================== reverse_view ===================

/**
 * @brief 惰性“反向迭代”视图，将底层范围逆序输出。
 * @tparam R 原始范围类型
 *
 * 设计初衷：
 * 1. 与 std::views::reverse 语义一致：迭代时从尾到头遍历。
 * 2. 不提前分配内存，迭代器类别与底层保持一致（若底层为 RandomAccess，则仍为 RandomAccess）。
 * 3. 支持 const 迭代，当底层范围支持 const begin/end 时可用。
 *
 * 实现要点：
 * 1. 内部保存 as_view_t<R>，按值存储，确保生命周期安全。
 * 2. begin() 返回 std::reverse_iterator(adl_end(r_))，end() 返回
 * std::reverse_iterator(adl_begin(r_))。
 * 3. 提供 const 重载，保证 const R 也能生成对应迭代器。
 */
template <class R>
class reverse_view
{
    using ItBase = range_begin_t<R>; ///< 底层迭代器类型

public:
    using iterator = std::reverse_iterator<ItBase>;                       ///< 反向迭代器
    using const_iterator = std::reverse_iterator<range_begin_t<const R>>; ///< const 反向迭代器

    /**
     * @brief 构造 reverse_view
     * @param r 原始范围（将 move 进内部）
     */
    explicit reverse_view(R r) : r_(std::move(r)) {}

    /**
     * @brief 返回起始反向迭代器（指向原范围末元素的下一位置）
     */
    iterator begin() { return iterator(adl_end(r_)); }

    /**
     * @brief 返回终止反向迭代器（指向原范围首元素的前一位置）
     */
    iterator end() { return iterator(adl_begin(r_)); }

    /**
     * @brief 返回 const 起始反向迭代器
     */
    const_iterator begin() const { return const_iterator(adl_end(static_cast<const R &>(r_))); }

    /**
     * @brief 返回 const 终止反向迭代器
     */
    const_iterator end() const { return const_iterator(adl_begin(static_cast<const R &>(r_))); }

private:
    R r_; ///< 视图化后的原始范围
};

/**
 * @brief reverse 视图的函数对象实现，支持管道化。
 * @details
 * 设计要点：
 * 1. 通过 operator() 直接构造 reverse_view，无需延迟绑定。
 * 2. 内部强制 decay 消除引用，确保视图按值语义管理资源。
 */
struct reverse_fn : pipeable<reverse_fn>
{
    /**
     * @brief 接收范围并生成 reverse_view。
     * @tparam R 原始范围类型（万能引用）
     * @param r  原始范围实例
     * @return   reverse_view<as_view_t<RR>>
     */
    template <class R>
    auto operator()(R && r) const
    {
        using RR = typename std::decay<R>::type;
        return reverse_view<as_view_t<RR>>(as_view(std::forward<R>(r)));
    }
};

/**
 * @brief 全局内联实例，提供 kp::reverse 调用点。
 */
inline constexpr reverse_fn reverse{};

// =================== take_while_view ===================

/**
 * @brief 惰性“按条件截取前缀”视图，遇到首个不满足谓词的元素即停止。
 * @tparam R   原始范围类型
 * @tparam Pred 一元谓词，返回 true 的元素被保留
 *
 * 设计初衷：
 * 1. 与 std::views::take_while 语义一致：迭代时持续输出元素，直到谓词返回 false。
 * 2. 不提前分配内存，迭代器类别与底层保持一致。
 * 3. 支持 const 迭代，当底层范围支持 const begin 时可用。
 *
 * 实现要点：
 * 1. 内部保存 as_view_t<R> 和 Pred 实例，均按值存储。
 * 2. end() 通过 take_while_end 辅助函数按需前进，直到首个不满足条件的元素。
 * 3. 提供 const 重载，保证 const R 也能生成对应迭代器。
 */
template <class R, class Pred>
class take_while_view
{
    using ItBase = range_begin_t<R>; ///< 底层迭代器类型
    using EndBase = range_end_t<R>;  ///< 底层哨兵类型

public:
    using iterator = ItBase;  ///< 迭代器类型与底层一致
    using sentinel = EndBase; ///< 哨兵类型与底层一致

    /**
     * @brief 构造 take_while_view
     * @param r 原始范围（将 move 进内部）
     * @param p 谓词函数（将 move 进内部）
     */
    take_while_view(R r, Pred p) : r_(std::move(r)), pred_(std::move(p)) {}

    /**
     * @brief 返回起始迭代器（non-const）
     */
    iterator begin() { return adl_begin(r_); }

    /**
     * @brief 返回终止迭代器（指向首个不满足条件的元素或底层结尾）
     */
    iterator end() { return take_while_end(adl_begin(r_), adl_end(r_), pred_); }

    /**
     * @brief 返回 const 起始迭代器
     */
    auto begin() const -> range_begin_t<const R> { return adl_begin(static_cast<const R &>(r_)); }

    /**
     * @brief 返回 const 终止迭代器
     */
    auto end() const -> range_begin_t<const R>
    {
        return take_while_end(
            adl_begin(static_cast<const R &>(r_)), adl_end(static_cast<const R &>(r_)), pred_);
    }

private:
    /**
     * @brief 辅助函数：从 it 出发，持续前进直到首个不满足 pred 的元素或到达 ed。
     * @tparam It 迭代器类型
     * @tparam Ed 哨兵类型
     * @tparam P  谓词类型
     * @param it 起始迭代器
     * @param ed 终止哨兵
     * @param p  谓词实例
     * @return   终止位置迭代器
     */
    template <class It, class Ed, class P>
    // Accept iterator/sentinel by const reference to avoid large-by-value ABI issues
    static It take_while_end(const It & it_in, const Ed & ed_in, const P & p)
    {
        auto it = it_in; // local copy to advance
        auto ed = ed_in;
        while (!iter_equal(it, ed) && p(*it))
            ++it;
        return it;
    }

    R r_;       ///< 视图化后的原始范围
    Pred pred_; ///< 谓词实例
};

/**
 * @brief take_while 视图的函数对象实现，支持管道化语法。
 * @details
 * 设计要点：
 * 1. 通过 binder 延迟绑定谓词，使 `range | take_while(pred)` 语法成为可能。
 * 2. 内部强制 decay 消除引用，确保视图按值语义管理资源。
 */
struct take_while_fn : pipeable<take_while_fn>
{
    /**
     * @brief 延迟绑定谓词的中间函子，负责最终构造 take_while_view。
     * @tparam P 谓词类型（可函数指针、函数对象、lambda）
     *
     * 设计要点：
     * 1. 继承 pipeable<binder<P>> 以获得 operator| 能力。
     * 2. 在 operator() 内部将范围包装为 as_view_t，确保迭代器语义统一。
     */
    template <class P>
    struct binder : pipeable<binder<P>>
    {
        P p; ///< 按值保存谓词，保证生命周期安全

        /**
         * @brief 构造 binder，按值接收谓词。
         * @param pp 谓词实例
         */
        explicit binder(P pp) : p(std::move(pp)) {}

        /**
         * @brief 接收范围并生成 take_while_view。
         * @tparam R 原始范围类型（万能引用）
         * @param r  原始范围实例
         * @return   take_while_view<as_view_t<RR>, PP>
         */
        template <class R>
        auto operator()(R && r) const
        {
            using RR = typename std::decay<R>::type;
            using PP = P;
            return take_while_view<as_view_t<RR>, PP>(as_view(std::forward<R>(r)), p);
        }
    };

    /**
     * @brief 接收谓词并返回延迟绑定的 binder。
     * @tparam P 谓词类型
     * @param p  谓词实例
     * @return   binder<P> 临时对象
     */
    template <class P>
    auto operator()(P && p) const
    {
        return binder<typename std::decay<P>::type>(std::forward<P>(p));
    }
};

/**
 * @brief 全局内联实例，提供 kp::take_while 调用点。
 */
inline constexpr take_while_fn take_while{};

// =================== drop_while_view ===================
/**
 * @brief 惰性“跳过满足谓词的前缀”视图。
 * @tparam R   原始范围类型
 * @tparam Pred 一元谓词，返回 true 的元素将被跳过
 *
 * 设计初衷：
 * 1. 与 std::views::drop_while 语义一致：迭代时从首个不满足 pred 的元素开始输出。
 * 2. 跳过阶段仅发生在 begin() 首次调用时，后续迭代器行为与底层一致，零额外开销。
 * 3. 支持 const 迭代，当底层范围支持 const begin 时可用。
 *
 * 实现要点：
 * 1. 内部保存 as_view_t<R> 与 Pred 实例，均按值存储，生命周期安全。
 * 2. begin() 通过私有静态辅助 drop_while_begin 定位到首个“不满足 pred”的元素。
 * 3. 迭代器类型直接复用底层 ItBase，因此类别能力完全保留（RandomAccess 仍为 RandomAccess）。
 */
template <class R, class Pred>
class drop_while_view
{
    using ItBase = range_begin_t<R>;
    using EndBase = range_end_t<R>;

public:
    using iterator = ItBase;  ///< 迭代器类型与底层完全一致
    using sentinel = EndBase; ///< 哨兵类型与底层完全一致

    /**
     * @brief 构造 drop_while_view
     * @param r 原始范围（将 move 进内部 as_view）
     * @param p 谓词函数（将 move 进内部）
     */
    drop_while_view(R r, Pred p) : r_(std::move(r)), pred_(std::move(p)) {}

    /**
     * @brief 返回起始迭代器（已跳过满足 pred 的前缀）
     */
    iterator begin() { return drop_while_begin(adl_begin(r_), adl_end(r_), pred_); }

    /**
     * @brief 返回终止哨兵
     */
    sentinel end() { return adl_end(r_); }

    /**
     * @brief 返回 const 起始迭代器
     */
    auto begin() const -> range_begin_t<const R>
    {
        return drop_while_begin(
            adl_begin(static_cast<const R &>(r_)), adl_end(static_cast<const R &>(r_)), pred_);
    }

    /**
     * @brief 返回 const 终止哨兵
     */
    auto end() const -> range_end_t<const R> { return adl_end(static_cast<const R &>(r_)); }

private:
    /**
     * @brief 从 it 出发，跳过连续满足 p(*it) 的元素，返回首个不满足或结尾。
     * @tparam It 迭代器类型
     * @tparam Ed 哨兵类型
     * @tparam P  谓词类型
     * @param it 起始迭代器
     * @param ed 终止哨兵
     * @param p  谓词实例
     * @return   定位后的迭代器
     */
    template <class It, class Ed, class P>
    // Accept iterator/sentinel by const reference to avoid large-by-value ABI issues
    static It drop_while_begin(const It & it_in, const Ed & ed_in, const P & p)
    {
        auto it = it_in; // local copy to advance
        auto ed = ed_in;
        while (!iter_equal(it, ed) && p(*it))
            ++it;
        return it;
    }

    as_view_t<R> r_; ///< 视图化后的原始范围
    Pred pred_;      ///< 谓词实例
};

/**
 * @brief drop_while_view 的函数对象版本，支持管道化语法。
 * @details
 * 设计初衷：
 * 1. 提供与 std::views::drop_while 一致的调用体验：range | drop_while(pred)。
 * 2. 通过 binder 延迟绑定谓词，使“先传 pred 再传 range”的柯里化写法成为可能。
 * 3. 所有状态按值存储，避免悬空引用，保证线程安全（无共享可变状态）。
 */
struct drop_while_fn : pipeable<drop_while_fn>
{
    /**
     * @brief 延迟绑定谓词的中间函子，负责最终构造 drop_while_view。
     * @tparam P 谓词类型（可函数指针、函数对象、lambda）
     *
     * 设计要点：
     * 1. 继承 pipeable<binder<P>> 以获得 operator| 能力。
     * 2. 在 operator() 内部将范围包装为 as_view_t，确保迭代器语义统一。
     */
    template <class P>
    struct binder : pipeable<binder<P>>
    {
        P p; ///< 按值保存谓词，保证生命周期安全

        /**
         * @brief 构造 binder，按值接收谓词。
         * @param pp 谓词实例
         */
        explicit binder(P pp) : p(std::move(pp)) {}

        /**
         * @brief 接收范围并生成 drop_while_view。
         * @tparam R 原始范围类型（万能引用）
         * @param r  原始范围实例
         * @return   drop_while_view<as_view_t<RR>, PP>
         *
         * 实现要点：
         * 1. 使用 as_view 包装原始范围，统一迭代器入口。
         * 2. 强制 decay 消除引用，避免视图内部出现引用成员。
         */
        template <class R>
        auto operator()(R && r) const
        {
            using RR = typename std::decay<R>::type;
            using PP = P;
            return drop_while_view<as_view_t<RR>, PP>(as_view(std::forward<R>(r)), p);
        }
    };

    /**
     * @brief 接收谓词并返回延迟绑定的 binder。
     * @tparam P 谓词类型
     * @param p  谓词实例
     * @return   binder<P> 临时对象
     */
    template <class P>
    auto operator()(P && p) const
    {
        return binder<typename std::decay<P>::type>(std::forward<P>(p));
    }
};

/**
 * @brief 全局内联实例，提供 kp::drop_while 调用点。
 */
inline constexpr drop_while_fn drop_while{};

// =================== enumerate_view ===================
/**
 * @brief 惰性“带索引枚举”视图，迭代时返回 {index, *elem} 的 std::pair。
 * @tparam R 原始范围类型
 *
 * 设计初衷：
 * 1. 与 Python 的 enumerate 类似，为每个元素附加从 0 开始递增的索引。
 * 2. 零额外内存分配，索引在迭代器内部维护，按需计算。
 * 3. 支持 const 迭代，当底层范围支持 const begin 时可用。
 *
 * 实现要点：
 * 1. 内部保存 as_view_t<R>，按值存储，生命周期安全。
 * 2. 迭代器 iter_t<Const> 模板同时支持 const / non-const 两套迭代器。
 * 3. operator* 返回 std::pair<std::size_t, reference>，不缓存结果，保证惰性。
 */
template <class R>
class enumerate_view
{
    using ItBase = range_begin_t<R>;
    using EndBase = range_end_t<R>;

    /**
     * @brief 实际迭代器，按需生成 {index, *it}。
     * @tparam Const 为 true 时代表 const 迭代器
     */
    template <bool Const>
    class iter_t
    {
        using View = typename std::conditional<Const, const enumerate_view, enumerate_view>::type;

    public:
        using value_type =
            std::pair<std::size_t, decltype(*std::declval<ItBase &>())>; ///< 返回类型
        using difference_type = std::ptrdiff_t;
        using iterator_category = std::input_iterator_tag; ///< 保守策略，仅保证 InputIterator

        iter_t() = default;

        /**
         * @brief 构造迭代器
         * @param v  指向父视图（未使用，预留扩展）
         * @param it 底层迭代器
         * @param ed 底层哨兵
         * @param i  当前索引
         */
        // Pass iterator/sentinel by const reference, store by value internally
        iter_t(View * v, const ItBase & it, const EndBase & ed, std::size_t i)
            : v_(v), it_(it), ed_(ed), i_(i)
        {}

        bool operator==(const iter_t & other) const { return iter_equal(it_, other.it_); }
        bool operator!=(const iter_t & other) const { return !(*this == other); }

        iter_t & operator++()
        {
            ++it_;
            ++i_;
            return *this;
        }
        iter_t operator++(int)
        {
            auto tmp = *this;
            ++*this;
            return tmp;
        }

        /**
         * @brief 惰性求值：返回 {index, *it}
         */
        value_type operator*() const { return {i_, *it_}; }

    private:
        View * v_{};       ///< 父视图指针（预留）
        ItBase it_{};      ///< 底层迭代器
        EndBase ed_{};     ///< 底层哨兵（预留）
        std::size_t i_{0}; ///< 当前索引
    };

public:
    using iterator = iter_t<false>;      ///< non-const 迭代器
    using const_iterator = iter_t<true>; ///< const 迭代器

    /**
     * @brief 构造 enumerate_view
     * @param r 原始范围（将 move 进内部 as_view）
     */
    explicit enumerate_view(R r) : r_(std::move(r)) {}

    /**
     * @brief 返回起始迭代器（索引从 0 开始）
     */
    iterator begin() { return iterator(this, adl_begin(r_), adl_end(r_), 0); }

    /**
     * @brief 返回终止迭代器
     */
    iterator end() { return iterator(this, adl_end(r_), adl_end(r_), 0); }

    /**
     * @brief 返回 const 起始迭代器
     */
    const_iterator begin() const
    {
        return const_iterator(
            this, adl_begin(static_cast<const R &>(r_)), adl_end(static_cast<const R &>(r_)), 0);
    }

    /**
     * @brief 返回 const 终止迭代器
     */
    const_iterator end() const
    {
        return const_iterator(
            this, adl_end(static_cast<const R &>(r_)), adl_end(static_cast<const R &>(r_)), 0);
    }

private:
    as_view_t<R> r_; ///< 视图化后的原始范围
};

/**
 * @brief enumerate_view 的函数对象版本，支持管道化语法。
 * @details
 * 设计初衷：
 * 1. 提供与 Python 类似的直观调用：range | enumerate。
 * 2. 通过 as_view 统一包装，确保与任意第三方容器无缝协作。
 * 3. 所有状态按值存储，避免悬空引用，保证线程安全。
 */
struct enumerate_fn : pipeable<enumerate_fn>
{
    /**
     * @brief 接收范围并生成 enumerate_view。
     * @tparam R 原始范围类型（万能引用）
     * @param r  原始范围实例
     * @return   enumerate_view<as_view_t<RR>>
     *
     * 实现要点：
     * 1. 使用 as_view 包装原始范围，统一迭代器入口。
     * 2. 强制 decay 消除引用，避免视图内部出现引用成员。
     */
    template <class R>
    auto operator()(R && r) const
    {
        using RR = typename std::decay<R>::type;
        return enumerate_view<as_view_t<RR>>(as_view(std::forward<R>(r)));
    }
};

/**
 * @brief 全局内联实例，提供 kp::enumerate 调用点。
 */
inline constexpr enumerate_fn enumerate{};

/**
 * @brief 半开整数区间视图 [first, last)
 * @note  仅支持 std::size_t 类型，若需泛型整数可再模板化。
 */
class iota_view
{
public:
    /**
     * @brief 满足 RandomAccessIterator 的轻量级迭代器
     * @details
     * 1. 所有操作均为 constexpr 友好（C++14 及以后）。
     * 2. 差值计算使用 std::ptrdiff_t，保证 64-bit 平台下大区间仍可表示。
     * 3. 不存储额外状态，仅一个 std::size_t 值，极致轻量。
     */
    class iterator
    {
    public:
        using iterator_category = std::random_access_iterator_tag;
        using value_type = std::size_t;
        using difference_type = std::ptrdiff_t;
        using pointer = const std::size_t *;   ///< 不提供可写地址，仅语法兼容
        using reference = const std::size_t &; ///< 同上，返回临时值

        /**
         * @brief 构造迭代器
         * @param v 当前整数值
         */
        explicit iterator(std::size_t v) noexcept : v_(v) {}

        /**
         * @brief 读取当前值（返回临时对象，避免悬挂引用）
         */
        value_type operator*() const noexcept { return v_; }

        /*@{*/
        /**
         * @brief 前置/后置自增
         */
        iterator & operator++() noexcept
        {
            ++v_;
            return *this;
        }
        iterator operator++(int) noexcept
        {
            auto t = *this;
            ++*this;
            return t;
        }
        /*@}*/

        /*@{*/
        /**
         * @brief 前置/后置自减
         */
        iterator & operator--() noexcept
        {
            --v_;
            return *this;
        }
        iterator operator--(int) noexcept
        {
            auto t = *this;
            --*this;
            return t;
        }
        /*@}*/

        /*@{*/
        /**
         * @brief 复合赋值运算
         */
        iterator & operator+=(difference_type d) noexcept
        {
            v_ += static_cast<std::size_t>(d);
            return *this;
        }
        iterator & operator-=(difference_type d) noexcept
        {
            v_ -= static_cast<std::size_t>(d);
            return *this;
        }
        /*@}*/

        /*@{*/
        /**
         * @brief 算术运算（友元函数，保证 int+iterator 也能工作）
         */
        friend iterator operator+(iterator it, difference_type d) noexcept
        {
            it += d;
            return it;
        }
        friend iterator operator+(difference_type d, iterator it) noexcept
        {
            it += d;
            return it;
        }
        friend iterator operator-(iterator it, difference_type d) noexcept
        {
            it -= d;
            return it;
        }
        /*@}*/

        /**
         * @brief 计算两迭代器距离
         * @note  结果可能为负，故返回 difference_type
         */
        friend difference_type operator-(const iterator & a, const iterator & b) noexcept
        {
            return static_cast<difference_type>(a.v_) - static_cast<difference_type>(b.v_);
        }

        /*@{*/
        /**
         * @brief 比较运算
         */
        bool operator==(const iterator & o) const noexcept { return v_ == o.v_; }
        bool operator!=(const iterator & o) const noexcept { return !(*this == o); }
        bool operator<(const iterator & o) const noexcept { return v_ < o.v_; }
        bool operator>(const iterator & o) const noexcept { return o < *this; }
        bool operator<=(const iterator & o) const noexcept { return !(o < *this); }
        bool operator>=(const iterator & o) const noexcept { return !(*this < o); }
        /*@}*/

    private:
        std::size_t v_{}; ///< 当前整数值
    };

    /**
     * @brief 构造区间视图
     * @param first 起始值（包含）
     * @param last  终止值（不包含）
     * @pre first <= last
     */
    iota_view(std::size_t first, std::size_t last) noexcept : b_(first), e_(last)
    {
        assert(first <= last && "iota_view requires first <= last");
    }

    /**
     * @brief 返回起始迭代器
     */
    iterator begin() const noexcept { return iterator(b_); }

    /**
     * @brief 返回终止迭代器
     */
    iterator end() const noexcept { return iterator(e_); }

private:
    std::size_t b_{}; ///< 起始值
    std::size_t e_{}; ///< 终止值
};

/**
 * @brief 生成 iota_view 的函数对象，支持管道化语法
 * @details
 * 用法示例：
 * @code
 * for (auto i : kp::iota(0, 10)) { ... }          // 直接调用
 * auto rng = kp::iota(0, 5) | kp::transform([](auto x){ return x*x; });
 * @endcode
 */
struct iota_fn : pipeable<iota_fn>
{
    /**
     * @brief 构造区间视图
     * @param a 起始值（包含）
     * @param b 终止值（不包含）
     * @return  iota_view 实例
     */
    auto operator()(std::size_t a, std::size_t b) const noexcept { return iota_view(a, b); }
};

/**
 * @brief 全局 constexpr 实例，提供 kp::iota 调用点
 */
inline constexpr iota_fn iota{};

/**
 * @brief 轻量“级联拼接”视图，将两个范围顺序连接。
 * @tparam R1 第一个范围类型
 * @tparam R2 第二个范围类型
 *
 * 设计初衷：
 * - 与 range-v3 的 concat/chain 语义一致：先遍历 r1，耗尽后遍历 r2。
 * - 惰性、零拷贝，元素以引用形式从底层范围透传。
 * - 迭代器类别保守为 InputIterator。
 */
template <class R1, class R2>
class concat_view
{
    using It1 = range_begin_t<R1>;
    using End1 = range_end_t<R1>;
    using It2 = range_begin_t<R2>;
    using End2 = range_end_t<R2>;

    template <bool Const>
    class iter_t
    {
        using View = typename std::conditional<Const, const concat_view, concat_view>::type;

    public:
        using iterator_category = std::input_iterator_tag;
        using difference_type = std::ptrdiff_t;
        using reference =
            decltype((std::declval<bool>() ? *std::declval<It1 &>() : *std::declval<It2 &>()));

        iter_t() = default;
        // Pass heavy iterator/sentinel types by const reference to avoid large-by-value ABI issues
        iter_t(View * v, const It1 & it1, const End1 & ed1, const It2 & it2, const End2 & ed2,
               bool on_first)
            : v_(v), it1_(it1), ed1_(ed1), it2_(it2), ed2_(ed2), on_first_(on_first)
        {
            satisfy();
        }

        void satisfy()
        {
            if (on_first_ && iter_equal(it1_, ed1_))
                on_first_ = false;
        }

        bool operator==(const iter_t & other) const
        {
            // 视为相等：都处于第二段且第二段迭代器相等，或都处于第一段且第一段迭代器相等
            if (on_first_ && other.on_first_)
                return iter_equal(it1_, other.it1_);
            if (!on_first_ && !other.on_first_)
                return iter_equal(it2_, other.it2_);
            // 特殊情况：当前在第二段且 other 在第一段的末尾，认为可能相等仅当 other 的 it1_==ed1_
            // 且 on_first_==false
            if (!on_first_ && other.on_first_)
                return iter_equal(other.it1_, other.ed1_) && iter_equal(it2_, other.it2_);
            if (on_first_ && !other.on_first_)
                return iter_equal(it1_, ed1_) && iter_equal(it2_, other.it2_);
            return false;
        }
        bool operator!=(const iter_t & other) const { return !(*this == other); }

        iter_t & operator++()
        {
            if (on_first_)
            {
                ++it1_;
                if (iter_equal(it1_, ed1_))
                    on_first_ = false;
            }
            else
            {
                ++it2_;
            }
            return *this;
        }
        iter_t operator++(int)
        {
            auto tmp = *this;
            ++*this;
            return tmp;
        }

        reference operator*() const { return on_first_ ? *it1_ : *it2_; }

    private:
        View * v_{};
        It1 it1_{};
        End1 ed1_{};
        It2 it2_{};
        End2 ed2_{};
        bool on_first_{true};
    };

public:
    using iterator = iter_t<false>;
    using const_iterator = iter_t<true>;

    concat_view(R1 r1, R2 r2) : r1_(std::move(r1)), r2_(std::move(r2)) {}

    iterator begin()
    {
        return iterator(this, adl_begin(r1_), adl_end(r1_), adl_begin(r2_), adl_end(r2_), true);
    }
    iterator end()
    {
        return iterator(this, adl_end(r1_), adl_end(r1_), adl_end(r2_), adl_end(r2_), false);
    }

    const_iterator begin() const
    {
        return const_iterator(this,
                              adl_begin(static_cast<const R1 &>(r1_)),
                              adl_end(static_cast<const R1 &>(r1_)),
                              adl_begin(static_cast<const R2 &>(r2_)),
                              adl_end(static_cast<const R2 &>(r2_)),
                              true);
    }
    const_iterator end() const
    {
        return const_iterator(this,
                              adl_end(static_cast<const R1 &>(r1_)),
                              adl_end(static_cast<const R1 &>(r1_)),
                              adl_end(static_cast<const R2 &>(r2_)),
                              adl_end(static_cast<const R2 &>(r2_)),
                              false);
    }

private:
    as_view_t<R1> r1_;
    as_view_t<R2> r2_;
};

/**
 * @brief concat 适配器的函数对象版本，支持管道化语法。
 * 用法：
 * - r1 | kp::concat(r2)
 * - r1 | kp::chain(r2)  // 别名
 */
struct concat_fn : pipeable<concat_fn>
{
    template <class R2>
    struct binder : pipeable<binder<R2>>
    {
        R2 r2; ///< 第二段范围，按值保存
        explicit binder(R2 rr) : r2(std::move(rr)) {}

        template <class R1>
        auto operator()(R1 && r1) const
        {
            using R1D = typename std::decay<R1>::type;
            using R2D = typename std::decay<R2>::type;
            return concat_view<as_view_t<R1D>, as_view_t<R2D>>(as_view(std::forward<R1>(r1)),
                                                               as_view(r2));
        }
    };

    template <class R2>
    auto operator()(R2 && r2) const
    {
        return binder<typename std::decay<R2>::type>(std::forward<R2>(r2));
    }
};

/**
 * @brief chain 的别名适配器（语义同 concat）。
 */
struct chain_fn : concat_fn {};

/**
 * @brief 全局 constexpr 实例，提供 kp::chain 调用点
 */
inline constexpr chain_fn chain{};

/**
 * @namespace kp::views
 * @brief 聚合所有视图适配器，模拟 std::views
 * @details
 * 1. 所有实体均为 inline constexpr 对象，ODR-used 安全。
 * 2. 名称与 std::views 保持一致，方便用户零成本切换。
 * 3. 未来若引入新适配器，只需在此追加一行即可全局可用。
 */
namespace views
{
inline constexpr transform_fn transform{};   ///< 惰性变换
inline constexpr filter_fn filter{};         ///< 惰性过滤
inline constexpr take_fn_impl take{};        ///< 取前 n 个
inline constexpr drop_fn drop{};             ///< 丢弃前 n 个
inline constexpr reverse_fn reverse{};       ///< 反转
inline constexpr take_while_fn take_while{}; ///< 条件取
inline constexpr drop_while_fn drop_while{}; ///< 条件丢弃
inline constexpr enumerate_fn enumerate{};   ///< 带索引枚举
inline constexpr iota_fn iota{};             ///< 整数区间
inline constexpr as_view_fn all{};           ///< 视图化包装，等价 std::views::all
inline constexpr concat_fn concat{}; ///< 级联拼接
inline constexpr chain_fn chain{};   ///< 别名
} // namespace views

} // namespace kp
#else

#include <ranges>

namespace kp
{

// 为兼容统一用法，聚合 std::views 并补充 concat/chain
namespace views
{
using std::views::all;
using std::views::drop;
using std::views::drop_while;
using std::views::enumerate;
using std::views::filter;
using std::views::iota;
using std::views::reverse;
using std::views::take;
using std::views::take_while;
using std::views::transform;
} // namespace views

// 同时在 kp 命名空间下直接暴露别名，以保持现有用法兼容
using std::views::all;
using std::views::drop;
using std::views::drop_while;
using std::views::enumerate;
using std::views::filter;
using std::views::iota;
using std::views::reverse;
using std::views::take;
using std::views::take_while;
using std::views::transform;

// =================== concat/chain for std::ranges branch ===================
// 标准库尚未收录 concat（C++26 计划），这里提供轻量实现，语义与上保持一致。

template <class R1, class R2>
class concat_view
{
    using It1 = decltype(std::begin(std::declval<R1 &>()));
    using End1 = decltype(std::end(std::declval<R1 &>()));
    using It2 = decltype(std::begin(std::declval<R2 &>()));
    using End2 = decltype(std::end(std::declval<R2 &>()));

    template <bool Const>
    class iter_t
    {
        using View = typename std::conditional<Const, const concat_view, concat_view>::type;

    public:
        using iterator_category = std::input_iterator_tag;
        using difference_type = std::ptrdiff_t;
        using reference = decltype((std::declval<bool>() ? *std::declval<It1 &>() : *std::declval<It2 &>()));

        iter_t() = default;
        // Pass heavy iterator/sentinel types by const reference to avoid large-by-value ABI issues
        iter_t(View * v, const It1 & it1, const End1 & ed1, const It2 & it2, const End2 & ed2,
               bool on_first)
            : v_(v), it1_(it1), ed1_(ed1), it2_(it2), ed2_(ed2), on_first_(on_first)
        {
            satisfy();
        }

        void satisfy()
        {
            if (on_first_ && it1_ == ed1_)
                on_first_ = false;
        }

        bool operator==(const iter_t & other) const
        {
            if (on_first_ && other.on_first_)
                return it1_ == other.it1_;
            if (!on_first_ && !other.on_first_)
                return it2_ == other.it2_;
            if (!on_first_ && other.on_first_)
                return other.it1_ == other.ed1_ && it2_ == other.it2_;
            if (on_first_ && !other.on_first_)
                return it1_ == ed1_ && it2_ == other.it2_;
            return false;
        }
        bool operator!=(const iter_t & other) const { return !(*this == other); }

        iter_t & operator++()
        {
            if (on_first_)
            {
                ++it1_;
                if (it1_ == ed1_)
                    on_first_ = false;
            }
            else
            {
                ++it2_;
            }
            return *this;
        }
        iter_t operator++(int)
        {
            auto tmp = *this;
            ++*this;
            return tmp;
        }

        reference operator*() const { return on_first_ ? *it1_ : *it2_; }

    private:
        View * v_{};
        It1 it1_{};
        End1 ed1_{};
        It2 it2_{};
        End2 ed2_{};
        bool on_first_{true};
    };

public:
    using iterator = iter_t<false>;
    using const_iterator = iter_t<true>;

    concat_view(R1 r1, R2 r2) : r1_(std::move(r1)), r2_(std::move(r2)) {}

    iterator begin()
    {
        return iterator(this, std::begin(r1_), std::end(r1_), std::begin(r2_), std::end(r2_), true);
    }
    iterator end()
    {
        return iterator(this, std::end(r1_), std::end(r1_), std::end(r2_), std::end(r2_), false);
    }

    const_iterator begin() const
    {
        return const_iterator(
            this,
            std::begin(static_cast<const R1 &>(r1_)),
            std::end(static_cast<const R1 &>(r1_)),
            std::begin(static_cast<const R2 &>(r2_)),
            std::end(static_cast<const R2 &>(r2_)),
            true);
    }
    const_iterator end() const
    {
        return const_iterator(
            this,
            std::end(static_cast<const R1 &>(r1_)),
            std::end(static_cast<const R1 &>(r1_)),
            std::end(static_cast<const R2 &>(r2_)),
            std::end(static_cast<const R2 &>(r2_)),
            false);
    }

private:
    R1 r1_;
    R2 r2_;
};

struct concat_fn : pipeable<concat_fn>
{
    template <class R2>
    struct binder : pipeable<binder<R2>>
    {
        R2 r2;
        explicit binder(R2 rr) : r2(std::move(rr)) {}

        template <class R1>
        auto operator()(R1 && r1) const
        {
            using R1D = typename std::decay<R1>::type;
            using R2D = typename std::decay<R2>::type;
            return concat_view<R1D, R2D>(std::forward<R1>(r1), r2);
        }
    };

    template <class R2>
    auto operator()(R2 && r2) const
    {
        return binder<typename std::decay<R2>::type>(std::forward<R2>(r2));
    }
};

struct chain_fn : concat_fn {};

// 在 kp 命名空间下暴露自定义 concat/chain 适配器
inline constexpr concat_fn concat{};
inline constexpr chain_fn chain{};

namespace views
{
inline constexpr concat_fn concat{};
inline constexpr chain_fn chain{};
} // namespace views

} // namespace kp

#endif
